<script setup lang="ts">
import { Icon, Loading } from 'vant'
import ThinkingProcess from './ThinkingProcess.vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'

interface Reference {
  title: string;
  url: string;
  content: string;
  [key: string]: any;
}

interface MessageProps {
  type: 'user' | 'ai';
  content: string;
  hasThinking?: boolean;
  thinking?: {
    content: string;
    done: boolean;
    time: number;
    startTime?: number;
  };
  hasReferences?: boolean;
  references?: Reference[];
  referenceCount?: number;
  isLoading?: boolean;
  isLast?: boolean;
}

const props = defineProps<MessageProps>()

const emit = defineEmits(['open-references'])

const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight: function (str: string, lang: string) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(str, { language: lang }).value
      } catch (__) { }
    }
    return ''
  }
})

const openReferences = () => {
  if (props.references && props.references.length > 0) {
    emit('open-references', props.references)
  }
}
</script>

<template>
  <div :class="['message-item', type === 'user' ? 'user-message' : 'ai-message']">
    <template v-if="type === 'user'">
      <div class="message-bubble user-bubble">
        {{ content }}
      </div>
    </template>

    <template v-else>
      <div class="ai-message-container">
        <div v-if="hasReferences" class="references-header" @click="openReferences">
          找到{{ referenceCount }}篇资料作为参考
          <Icon name="arrow" />
        </div>

        <div class="message-bubble ai-bubble">
          <div v-if="isLoading && isLast && !hasThinking && !content" class="loading-dots">
            <span></span>
            <span></span>
            <span></span>
          </div>

          <ThinkingProcess v-if="hasThinking && thinking?.content" :thinking="!thinking?.done"
            :content="thinking?.content || ''" :time="thinking?.time || 0" :done="thinking?.done || false" />

          <div v-if="hasThinking && thinking?.done && thinking?.content && content" class="separator"></div>

          <div v-if="content" class="markdown-content" v-html="md.render(content)"></div>
        </div>
      </div>
    </template>
  </div>
</template>

<style lang="scss" scoped>
.message-item {
  display: flex;
  margin-bottom: 16px;

  &.user-message {
    justify-content: flex-end;
  }

  &.ai-message {
    justify-content: flex-start;
  }

  .message-bubble {
    max-width: 90%;
    padding: 14px 16px;
    border-radius: 18px;
    word-break: break-word;

    &.user-bubble {
      background: linear-gradient(135deg, #4080ff, #3a75e9);
      color: white;
      border-top-right-radius: 4px;
      box-shadow: 0 2px 8px rgba(64, 128, 255, 0.2);
    }

    &.ai-bubble {
      width: 90%;
      background-color: white;
      color: #333;
      border-top-left-radius: 4px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);

      .loading-dots {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 24px;

        span {
          display: inline-block;
          width: 8px;
          height: 8px;
          margin: 0 2px;
          background-color: #ccc;
          border-radius: 50%;
          animation: dot-flashing 1s infinite alternate;

          &:nth-child(2) {
            animation-delay: 0.2s;
          }

          &:nth-child(3) {
            animation-delay: 0.4s;
          }
        }
      }

      .separator {
        height: 1px;
        background-color: #eee;
        margin: 12px 0;
        width: 100%;
      }

      .markdown-content {
        line-height: 1.5;

        :deep(pre) {
          background-color: #f5f7fa;
          padding: 12px;
          border-radius: 8px;
          overflow-x: auto;
          margin: 8px 0;
        }

        :deep(code) {
          font-family: 'Courier New', Courier, monospace;
          background-color: #f5f7fa;
          padding: 2px 4px;
          border-radius: 4px;
        }

        :deep(p) {
          margin: 8px 0;
        }

        :deep(ul),
        :deep(ol) {
          padding-left: 20px;
          margin: 8px 0;
        }

        :deep(h1),
        :deep(h2),
        :deep(h3),
        :deep(h4),
        :deep(h5),
        :deep(h6) {
          margin: 16px 0 8px;
        }

        :deep(table) {
          border-collapse: collapse;
          width: 100%;
          margin: 12px 0;

          th,
          td {
            border: 1px solid #eee;
            padding: 8px;
            text-align: left;
          }

          th {
            background-color: #f5f7fa;
          }
        }

        :deep(blockquote) {
          border-left: 4px solid #ddd;
          padding-left: 16px;
          color: #666;
          margin: 12px 0;
        }

        &.fade-in {
          animation: fadeIn 0.3s ease-in-out;
        }

        :deep(a) {
          color: #4080ff;
          text-decoration: none;
          cursor: pointer;
        }

        :deep(.reference-link) {
          color: #4080ff;
          cursor: pointer;
          font-weight: 500;
          padding: 4px 0;
          display: inline-block;
        }
      }
    }
  }

  .ai-message-container {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    width: 100%;

    .references-header {
      background-color: rgba(64, 128, 255, 0.1);
      color: #4080ff;
      padding: 8px 14px;
      border-radius: 16px;
      font-size: 14px;
      cursor: pointer;
      display: flex;
      align-items: center;
      gap: 6px;
      margin-bottom: 10px;
      box-shadow: 0 1px 4px rgba(64, 128, 255, 0.1);

      &:active {
        background-color: rgba(64, 128, 255, 0.15);
      }

      .van-icon {
        font-size: 12px;
        margin-left: 2px;
      }
    }
  }
}

@keyframes dot-flashing {
  0% {
    opacity: 0.2;
  }

  100% {
    opacity: 1;
  }
}
</style>
